package thread;

public class Demo10 {
    //中断一个线程->终止一个线程
    //比如：
    public static void main2(String[] args) throws InterruptedException {
        boolean isFinished2 = false;
        Thread t = new Thread(() -> {
            while(!isFinished2) {
                //这里报错是因为后面对于这个isFinished2进行了修改，形成了变量捕获问题，lambda里面的问题
                System.out.println(Thread.currentThread().getName());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            System.out.println(Thread.currentThread().getName() + "结束");
        });
        t.start();
        Thread.sleep(3000);
        //当这个不进行修改就不会出现变量捕获问题的异常
        //isFinished2 = true;
    }
    //方法一：内部类使用外部类的成员变量
    //这个方法呢，我们的外部类的变量不能变成局部变量，因为这样的话就会出现lambda表达式的 变量捕获 问题了
    private static boolean isFinished = false;
    public static void main1(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
           while(!isFinished) {
               System.out.println(Thread.currentThread().getName());
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }
           }
            System.out.println(Thread.currentThread().getName() + "结束");
        });
        t.start();

        Thread.sleep(3000);
        isFinished = true;
    }

    //方法二：调用 interrupt() ⽅法来通知
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
           //这里我们使用Thread.currentThread()的到线程的名字
           //这里使用 isInterrupted() 来判断线程是否结束了，结束了就是true取反就是false
           while(!Thread.currentThread().isInterrupted()) {
               System.out.println("hello thread");
               try {
                   //睡眠1秒
                   Thread.sleep(1000);
                   //这个抛出异常是因为可能 在执行sleep的时候呢，就会被唤醒就抛出异常是线程结束，从而使进程结束
               } catch (InterruptedException e) {
                   //这里会抛出异常，因为我们的 interrupt() 方法把 sleep() 这个方法 “唤醒” 进而抛出异常
                   //如果不行抛出异常，这里就不抛异常，直接 break
                   //throw new RuntimeException(e);
                   break;
                   //当这里什么也不设置，虽然 interrupt()会设置线程的标志为设成true，但是在唤醒sleep之后呢，会再次设置标志位为false
                   //所以这里有三种情况：
                   //1、加上break就是立即终止
                   //2、catch 里先执行一些其他的逻辑再break，就是稍后终止
                   //3、啥都不写，就是不终止
               }
           }
            System.out.println("t 结束");
        });
        t.start();

        Thread.sleep(3000);
        //修改线程，设置为结束
        System.out.println("main 线程尝试终止 t线程");
        t.interrupt();
    }
}
